package log

import (
	"log"
	"os"
	"fmt"
	"time"
	"io"
)

// 日志服务
const (
	LOGLEVEL_INFO	= iota
	LOGLEVEL_DEBUG
	LOGLEVEL_WARN
	LOGLEVEL_ERROR
)

// 日志对象
type CSLogger struct {
	logger 	*log.Logger
	logLevel 	int
	logFile 	*os.File

	StackIndex	int 	// 显示打印位置的序号
}

func NewLogger(level int, isDebug bool, outName string) *CSLogger {
	out := &CSLogger{}
	out.logLevel = level
	out.StackIndex = 2
	fmt.Println("Log Level", level, "isDebug", isDebug, "outName", outName)

	if "" != outName {
		err := os.MkdirAll("log", 0777)
		if err == nil {
			f, err := os.OpenFile(fmt.Sprintf("log/%s-%s.log", outName, time.Now().Format("2006-01-02")), os.O_WRONLY | os.O_APPEND | os.O_CREATE | os.O_SYNC, 0777)
			if err == nil {
				out.logFile = f
				if isDebug {
					out.logger = log.New(io.MultiWriter(f, os.Stdout), "[CS] ", log.LstdFlags | log.Lshortfile)
				} else {
					out.logger = log.New(f, "[CS] ", log.LstdFlags | log.Lshortfile)
				}

				// 启动隔天切换日志文件协程
				go func() {
					now := time.Now()
					dt := time.Date(now.Year(), now.Month(), now.Day() + 1, 0, 0, 0, 0, time.Local).Sub(now)
					t := time.After(dt)
					for {
						select {
						case <- t:
							f, err := os.OpenFile(fmt.Sprintf("log/%s-%s.log", outName, time.Now().Format("2006-01-02")), os.O_WRONLY | os.O_APPEND | os.O_CREATE | os.O_SYNC, 0777)
							if err == nil {
								if isDebug {
									out.logger.SetOutput(io.MultiWriter(f, os.Stdout))
								} else {
									out.logger.SetOutput(f)
								}
								f2 := out.logFile
								out.logFile = f
								if f2 != nil {
									f2.Close()
								}
							}
							t = time.After(24 * time.Hour)
						}
					}
				}()

				return out
			} else {
				fmt.Println(err)
			}
		} else {
			fmt.Println(err)
		}
	}

	out.logger = log.New(os.Stdout, "[CS] ", log.LstdFlags | log.Lshortfile)	
	return out
}

func (out *CSLogger) CloseLogger() {
	if out.logFile != nil {
		out.logFile.Close()
		out.logFile = nil
	}
}

func (out *CSLogger) IsLogInfo() bool {
	return out.logLevel <= LOGLEVEL_INFO
}

func (out *CSLogger) Info(v ...interface{}) {
	if out.logLevel <= LOGLEVEL_INFO {
		out.logger.Output(out.StackIndex, fmt.Sprintln(v...))
	}
}

func (out *CSLogger) Track(v ...interface{}) {
	if out.logLevel <= LOGLEVEL_DEBUG {
		//logger.Print("[TRACK]")
		out.logger.Output(out.StackIndex, fmt.Sprintln(v...))
	}
}

func (out *CSLogger) Print(v ...interface{}) {
	if out.logLevel <= LOGLEVEL_DEBUG {
		//logger.Print("[TRACK]")
		out.logger.Output(out.StackIndex, fmt.Sprintln(v...))
	}
}

func (out *CSLogger) Warn(v ...interface{}) {
	if out.logLevel <= LOGLEVEL_WARN {
		//logger.Print("[WARN]")
		out.logger.Output(out.StackIndex, fmt.Sprintln(v...))
	}
}

func (out *CSLogger) Error(v ...interface{}) {
	if out.logLevel <= LOGLEVEL_ERROR {
		//logger.Print("[ERROR]")
		out.logger.Output(out.StackIndex, fmt.Sprintln(v...))
	}
}

func (out *CSLogger) Panic(v ...interface{}) {
	if out.logLevel <= LOGLEVEL_ERROR {
		s := fmt.Sprintln(v...)
		out.logger.Output(out.StackIndex, s)
		panic(s)
	}
}

// 打印日志，第一个参数为打印位置序号
func (out *CSLogger) Output(v ...interface{}) {
	i, ok := v[0].(int)
	if ok {
		out.logger.Output(i, fmt.Sprintln(v[1:]...))
	} else {
		out.logger.Output(out.StackIndex, fmt.Sprintln(v...))
	}
}

var logger *CSLogger

func InitLog(level int, isDebug bool, outName string) {
	logger = NewLogger(level, isDebug, outName)
	logger.StackIndex = 3
}

func CloseLogger() {
	logger.CloseLogger()
}

func IsLogInfo() bool {
	return logger.IsLogInfo()
}

func Info(v ...interface{}) {
	logger.Info(v ...)
}

func Track(v ...interface{}) {
	logger.Track(v ...)
}

func Warn(v ...interface{}) {
	logger.Warn(v ...)
}

func Error(v ...interface{}) {
	logger.Error(v ...)
}

func Panic(v ...interface{}) {
	logger.Panic(v ...)
}

func Output(v ...interface{}) {
	logger.Output(v ...)
}

var Print = Track